/*
 * random_test2
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>

#include "random_test2.h"
#include "../slab/mm.h"

void run_random_test2()
{
    struct timeval time1, time2;
    int data[100];
    int i=0, j =0, size = 0, time = 0, total_bytes = 0;
    float mem_util = 0.0f;
    FILE* fp1 = 0;

    fp1 = fopen("test_random2","a");
    if (!fp1)
    {
        fprintf(stderr, "can not open file for logging!");
        exit (1);
    }

    int fix_sizes[] = {32,64,128,256,512,1024,2048,4096,8192,16384};

    srandom(random());

    printf("using libc, please wait...");fflush(stdout);

    gettimeofday(&time1, 0);

    mem_util = 0;

    for (i = 0; i<1000; ++i)
    {
        total_bytes = 0;
        for (j=0; j<100; ++j)
        {
            size = fix_sizes[j%10];
            total_bytes += size;
            data[j] = (int)malloc(size);
            memset((void*)(data[j]),'A',size);
        }
        mem_util = (mem_util*i + total_bytes*1.0f/(1*PAGE_SIZE)*100)/(i+1); // this is just for fairness, no practical use

        for (j=0; j<100; ++j)
        {
            free((void*)(data[j]));
        }
    }

    gettimeofday(&time2, 0);

    printf("done\n");

    time = abs(time2.tv_usec-time1.tv_usec);
    printf("time=%dus\t\tthroughput=%.2g\n",
            time,
            200000.0f*1000000/time);
    fprintf(fp1,"%.4g  ",
            200000.0f*1000000/time);

    printf("initializing our slab implementation, please wait...");fflush(stdout);

    mm_init(true);

    printf("done\n");

    printf("using our slab implementation, please wait...");fflush(stdout);

    gettimeofday(&time1, 0);

    mem_util = 0;

    for (i = 0; i<1000; ++i)
    {
        total_bytes = 0;
        for (j=0; j<100; ++j)
        {
            size = fix_sizes[j%10];
            total_bytes += size;
            data[j] = (int)mm_malloc(size);
            memset((void*)(data[j]),'A',size);
        }
        mem_util = (mem_util*i + total_bytes*1.0f/(page_occupied*PAGE_SIZE)*100)/(i+1);

        for (j=0; j<100; ++j)
        {
            mm_free((void*)(data[j]));
        }
    }

    gettimeofday(&time2, 0);

    printf("done\n");

    time = abs(time2.tv_usec-time1.tv_usec);
    printf("time=%dus\t\tthroughput=%.2g\t\tutilization=%.2f\n",
            time,
            200000.0f*1000000/time,
            mem_util);
    fprintf(fp1,"%.4g %.2f\n",
            200000.0f*1000000/time,
            mem_util);

    printf("un-initializing our slab implementation, please wait...");fflush(stdout);

    mm_deinit();

    printf("done\n");

    fclose(fp1);
}
